﻿using System;
using System.Reflection;
using System.Data;

namespace EnterpriseFramework.DataAccess
{
    /// <summary>
    /// Represents a column based on a field.
    /// </summary>
    public class FieldColumn : AbstractColumn
    {
        private FieldInfo field;

        /// <summary>
        /// Creates a new field column.
        /// </summary>
        /// <param name="field">underlying class field</param>
        /// <param name="name">column name</param>
        /// <param name="dbtype">database data type</param>
        /// <param name="size">size of the database data type</param>
        /// <param name="precision">precision of the database data type</param>
        /// <param name="scale">scale of the database data type</param>
        /// <param name="primaryKey">whether this column is a primary key column</param>
        /// <param name="autoIncr">whether this column is an auto-incremented column</param>
        /// <param name="concurrency">whether this column is used for concurrency checks</param>
        public FieldColumn(FieldInfo field, string name, DbType dbtype, int size, bool allowNull, bool isComputed,
            bool isReadOnly, bool primaryKey, bool autoIncr, bool _isUnique, bool concurrency)
            : base(name, dbtype, size, allowNull, isComputed, isReadOnly, primaryKey, autoIncr, _isUnique, concurrency
            , field.Name)
        {
            this.field = field;
        }

        /// <summary>
        /// True if this column can be written to. That is,
        /// whether calling the Write method can actually
        /// attempt to write a value into a target object.
        /// </summary>
        public override bool Writeable
        {
            get { return true; }
        }

        /// <summary>
        /// True if this column can be read from. That is,
        /// whether calling the Read method will return a valid value.
        /// </summary>
        public override bool Readable
        {
            get { return true; }
        }

        /// <summary>
        /// Attempts to write a given value info a given target object.
        /// </summary>
        /// <param name="target">target object</param>
        /// <param name="value">value to write</param>
        public override void Write(object target, object value)
        {
            field.SetValue(target, value);
        }

        /// <summary>
        /// Attempts to read a value from a given source object.
        /// </summary>
        /// <param name="source">source object</param>
        /// <returns>value of this column from the source object</returns>
        public override object Read(object source)
        {
            return field.GetValue(source);
        }
    }
}
